/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.upgrade.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.auth.impl.RealOrganizationUser;
import com.je.common.base.DynaBean;
import com.je.common.base.document.InternalFileBO;
import com.je.common.base.document.InternalFileUpload;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.service.rpc.DocumentInternalRpcService;
import com.je.common.base.service.rpc.UpgradeModulePackageRpcService;
import com.je.common.base.upgrade.PackageFile;
import com.je.common.base.upgrade.PackageResult;
import com.je.common.base.upgrade.UpgradeResourcesEnum;
import com.je.common.base.util.*;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.exception.UpgradeException;
import com.je.meta.service.upgrade.UpgradeService;
import com.je.meta.util.enumUtil.UpgradeFilePathEnum;
import com.je.meta.util.enumUtil.UpgradeInstallStateEnum;
import com.je.servicecomb.RpcSchemaFactory;
import org.apache.servicecomb.provider.pojo.RpcReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import static com.je.servicecomb.JECloud.*;

@Service
public class UpgradeServiceImpl implements UpgradeService {

    private static final Logger logger = LoggerFactory.getLogger(UpgradeServiceImpl.class);

    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private UpgradeModulePackageRpcService metaUpgradeModulePackageRpcService;
    @RpcReference(microserviceName = "rbac", schemaId = "upgradeModulePackageRpcService")
    private UpgradeModulePackageRpcService rbacUpgradeModulePackageRpcService;
    @RpcReference(microserviceName = "workflow", schemaId = "upgradeModulePackageRpcService")
    private UpgradeModulePackageRpcService workflowUpgradeModulePackageRpcService;
    @Autowired
    private Environment environment;
    @Autowired
    private DocumentInternalRpcService documentInternalRpcService;

    @Override
    public void insertPackageFuncs(String upgradeId, String funcIds) {
        insertPackageResource(upgradeId, funcIds, "func");
    }

    @Override
    public void insertPackageTables(String upgradeId, String tableIds) {
        insertPackageResource(upgradeId, tableIds, "table");
    }

    @Override
    public void insertPackageDictionarys(String upgradeId, String dictionaryIds) {
        List<String> dictionaryIdList = new ArrayList<>(Splitter.on(",").splitToList(dictionaryIds));
        List<DynaBean> dictionaryBeanList = metaService.select("JE_CORE_DICTIONARY", ConditionsWrapper.builder()
                .in("JE_CORE_DICTIONARY_ID", dictionaryIdList).apply("and (SY_STATUS = '' or SY_STATUS = '1' or SY_STATUS is NULL)"));
        DynaBean upgradePackage = metaService.selectOneByPk("JE_META_UPGRADEPACKAGE", upgradeId);
        deleteResourceByType(upgradeId, "dictionary");
        for (DynaBean eachDictionaryBean : dictionaryBeanList) {
            DynaBean detailBean = new DynaBean("JE_META_UPGRADERESOURCE", false);
            detailBean.set("UPGRADERESOURCE_TYPE_NAME", "数据字典");
            detailBean.set("UPGRADERESOURCE_TYPE_CODE", "dictionary");
            detailBean.set("UPGRADERESOURCE_CONTENT_NAME", eachDictionaryBean.getStr("DICTIONARY_DDNAME"));
            detailBean.set("UPGRADERESOURCE_CONTENT_CODE", eachDictionaryBean.getStr("JE_CORE_DICTIONARY_ID"));
            detailBean.set("UPGRADERESOURCE_CONTENT_BM", eachDictionaryBean.getStr("DICTIONARY_DDCODE"));
            detailBean.set("JE_META_UPGRADEPACKAGE_ID", upgradeId);
            detailBean.set("UPGRADERESOURCE_CODE", eachDictionaryBean.getStr("DICTIONARY_DDCODE"));
            detailBean.set("SY_PRODUCT_CODE", upgradePackage.getStr("SY_PRODUCT_NAME"));
            detailBean.set("SY_PRODUCT_ID", upgradePackage.getStr("SY_PRODUCT_ID"));
            detailBean.set("SY_PRODUCT_NAME", upgradePackage.getStr("SY_PRODUCT_CODE"));
            commonService.buildModelCreateInfo(detailBean);
            metaService.insert(detailBean);
        }
    }

    @Override
    public void insertPackageGlobalScripts(String upgradeId, String scriptIds) {
        insertPackageResource(upgradeId, scriptIds, "globalScript");
    }

    @Override
    public void insertPackageSystemVariables(String upgradeId, String variableIds) {
        insertPackageResource(upgradeId, variableIds, "variable");
    }

    @Override
    public void insertPackageBusinessData(String upgradeId, String tableIds) {
        insertPackageResource(upgradeId, tableIds, "business");
    }

    @Override
    public String insertPackageResource(String upgradeId, String sourceIds, String type) {
        DynaBean upgradePackage = metaService.selectOneByPk("JE_META_UPGRADEPACKAGE", upgradeId);
        UpgradeResourcesEnum upgradeResourcesEnum = UpgradeResourcesEnum.getUpgradeResourcesEnumByType(type);
        //check
        DynaBean resourceTable = metaService.selectOne("JE_CORE_RESOURCETABLE", ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", upgradeResourcesEnum.getTableCode()));
        if (resourceTable == null) {
            throw new PlatformException(upgradeResourcesEnum.getName() + "没有找到！", PlatformExceptionEnum.JE_CORE_TABLE_NOFIND_ERROR);
        }
        //根据主键查询资源信息
        List<String> sourceList = new ArrayList<>(Splitter.on(",").splitToList(sourceIds));
        List<DynaBean> beanList = metaService.select(upgradeResourcesEnum.getTableCode(), ConditionsWrapper.builder()
                .in(upgradeResourcesEnum.getContentCode(), sourceList));
        deleteResourceByType(upgradeId, upgradeResourcesEnum.getType());
        for (DynaBean bean : beanList) {
            DynaBean detailBean = new DynaBean("JE_META_UPGRADERESOURCE", false);
            detailBean.set("UPGRADERESOURCE_TYPE_NAME", upgradeResourcesEnum.getName());
            detailBean.set("UPGRADERESOURCE_TYPE_CODE", type);
            detailBean.set("UPGRADERESOURCE_CONTENT_BM", bean.getStr(upgradeResourcesEnum.getContentBm()));
            detailBean.set("UPGRADERESOURCE_CONTENT_NAME", bean.getStr(upgradeResourcesEnum.getContentName()));
            detailBean.set("UPGRADERESOURCE_CONTENT_CODE", bean.getStr(upgradeResourcesEnum.getContentCode()));
            detailBean.set("UPGRADERESOURCE_REMARK", bean.getStr(upgradeResourcesEnum.getRemark()));
            detailBean.set("JE_META_UPGRADEPACKAGE_ID", upgradeId);
            detailBean.set("SY_PRODUCT_CODE", upgradePackage.getStr("SY_PRODUCT_NAME"));
            detailBean.set("SY_PRODUCT_ID", upgradePackage.getStr("SY_PRODUCT_ID"));
            detailBean.set("SY_PRODUCT_NAME", upgradePackage.getStr("SY_PRODUCT_CODE"));
            commonService.buildModelCreateInfo(detailBean);
            metaService.insert(detailBean);
        }
        return "";
    }

    @Override
    public PackageResult doPackage(DynaBean upgradeBean) {
        String prodcutId = upgradeBean.getStr("SY_PRODUCT_ID");
        DynaBean prodcutBean = metaService.selectOneByPk("JE_PRODUCT_MANAGE", prodcutId);
        if (prodcutBean == null) {
            throw new UpgradeException(MessageUtils.getMessage("upgrade.product.notExits"));
        }
        PackageResult metaPackageResult = metaUpgradeModulePackageRpcService.packageModule(upgradeBean);
        PackageResult rbacPackageResult = rbacUpgradeModulePackageRpcService.packageModule(upgradeBean);
        PackageResult workflowPackageResult = workflowUpgradeModulePackageRpcService.packageModule(upgradeBean);
        PackageResult mergeAllPackageResult = metaPackageResult;
        mergeAllPackageResult.setUpgrade(upgradeBean);
        mergeAllPackageResult.setProduct(prodcutBean);
        //rbac
        mergeAllPackageResult.setProductRoles(rbacPackageResult.getProductRoles());
        mergeAllPackageResult.setProductMenus(rbacPackageResult.getProductMenus());
        mergeAllPackageResult.setProductTopMenus(rbacPackageResult.getProductTopMenus());
        mergeAllPackageResult.setRolePerms(rbacPackageResult.getRolePerms());
        mergeAllPackageResult.setProductPerms(rbacPackageResult.getProductPerms());
        //工作流
        mergeAllPackageResult.setProductWorkflows(workflowPackageResult.getProductWorkflows());
        //打包业务数据
        Map<String, String> businessMap = (Map<String, String>) upgradeBean.get(UpgradeResourcesEnum.BUSINESS.getAddListName());
        Map<String, List<DynaBean>> businessDataMap = new HashMap<>();
        mergeAllPackageResult.setBusinessDataMap(businessDataMap);
        if (businessMap == null || businessMap.size() == 0) {
            return mergeAllPackageResult;
        }
        if (PRODUCT_CORE_META.equals(prodcutBean.getStr("PRODUCT_CODE"))) {
            businessDataMap = metaUpgradeModulePackageRpcService.packageBusinessData(businessMap);
        } else if (PRODUCT_CORE_WORKFLOW.equals(prodcutBean.getStr("PRODUCT_CODE"))) {
            businessDataMap = workflowUpgradeModulePackageRpcService.packageBusinessData(businessMap);
        } else if (PRODUCT_CORE_RBAC.equals(prodcutBean.getStr("PRODUCT_CODE"))) {
            businessDataMap = rbacUpgradeModulePackageRpcService.packageBusinessData(businessMap);
        } else {
            UpgradeModulePackageRpcService upgradeModulePackageRpcService = RpcSchemaFactory.getRemoteProvierClazz(prodcutBean.getStr("PRODUCT_CODE"),
                    "upgradeModulePackageRpcService", UpgradeModulePackageRpcService.class);
            businessDataMap = upgradeModulePackageRpcService.packageBusinessData(businessMap);
        }
        mergeAllPackageResult.setBusinessDataMap(businessDataMap);
        //添加业务附件
        List<PackageFile> businessFiles = new ArrayList<>();
        if (upgradeBean.get("businessFileField") != null) {
            Map<String, String> businessFileField = (Map<String, String>) upgradeBean.get("businessFileField");
            addBusinessFiles(businessFiles, businessFileField, businessDataMap);
        }

        mergeAllPackageResult.getFiles().addAll(businessFiles);
        mergeAllPackageResult.setProductCode(upgradeBean.getStr("UPGRADEPACKAGE_YWCPBM"));
        mergeAllPackageResult.setProductName(upgradeBean.getStr("UPGRADEPACKAGE_YWCPMC"));
        return mergeAllPackageResult;
    }

    private void addBusinessFiles(List<PackageFile> businessFiles, Map<String, String> businessFileField,
                                  Map<String, List<DynaBean>> businessDataMap) {
        //附件信息配置
        for (String tableCode : businessFileField.keySet()) {
            if (businessDataMap.get(tableCode).size() == 0) {
                continue;
            }
            List<DynaBean> dynaBeanList = businessDataMap.get(tableCode);
            String fileds = businessFileField.get(tableCode);
            if (Strings.isNullOrEmpty(fileds)) {
                continue;
            }
            String[] filedArray = fileds.split(",");
            //遍历bean，获取附件字段信息
            for (String filed : filedArray) {
                for (DynaBean dynaBean : dynaBeanList) {
                    String value = dynaBean.getStr(filed);
                    if (!Strings.isNullOrEmpty(value)) {
                        businessFiles.add(new PackageFile.Builder()
                                .upgradeResourcesType("businessFile")
                                .fileCode(filed)
                                .pkValue(dynaBean.getPkValue())
                                .tableCode(tableCode)
                                .value(value)
                                .build());
                    }
                }
            }
        }
    }

    @Override
    public String doInstall(String pkValue, String fileKey) {
        File file = documentInternalRpcService.readFile(fileKey);
        if (file == null) {
            throw new UpgradeException(MessageUtils.getMessage("upgrade.file.notExits"));
        }
        if (metaService.select("JE_CORE_RESOURCETABLE",
                ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", "JE_META_UPGRADERESOURCE_IMPL")).size() > 0) {
            metaService.delete("JE_META_UPGRADERESOURCE_IMPL", ConditionsWrapper.builder().eq("JE_META_UPGRADEPACKAGE_ID", pkValue));
        }
        StringBuffer error = new StringBuffer();
        String upgradepackageRemark = "";
        try {
            upgradepackageRemark = installResources(file, pkValue);
        } catch (Exception e) {
            for (StackTraceElement element : e.getStackTrace()) {
                error.append("at " + element.toString());
            }
        }

        //更新安装包状态
        DynaBean dynaBean = new DynaBean("JE_META_UPGRADEINSTALL", false);
        dynaBean.setStr("UPGRADEINSTALL_INSTALL_TIME", DateUtils.formatDateTime(new Date()));
        dynaBean.setStr("UPGRADEINSTALL_INSTALL_CODE", UpgradeInstallStateEnum.INSTALL.getValue());
        dynaBean.setStr("UPGRADEINSTALL_INSTALL_NAME", UpgradeInstallStateEnum.INSTALL.getName());
        dynaBean.setStr("UPGRADEINSTALL_REMARK", upgradepackageRemark);
        if (error.length() == 0) {
            dynaBean.setStr("UPGRADEINSTALL_EXECUTION_STATUS", "3");
            dynaBean.setStr("UPGRADEINSTALL_YCXX", "");
        } else {
            dynaBean.setStr("UPGRADEINSTALL_EXECUTION_STATUS", "2");
            dynaBean.setStr("UPGRADEINSTALL_YCXX", error.toString());
        }
        commonService.buildModelModifyInfo(dynaBean);
        metaService.update(dynaBean, ConditionsWrapper.builder().eq("JE_META_UPGRADEINSTALL_ID", pkValue));
        return null;
    }

    private String installResources(File file, String pkValue) {
        metaService.delete("JE_META_UPGRADELOG", ConditionsWrapper.builder()
                .eq("JE_META_UPGRADEINSTALL_ID", pkValue));
        StringBuffer upgradepackageRemark = new StringBuffer();
        String json = getcontentJson(file);
        List<PackageResult> list = new ArrayList<>();

        try {
            JSONArray jsonArray = JSONArray.parseArray(json);
            for (int i = 0; i < jsonArray.size(); i++) {
                PackageResult packageResult = JSON.parseObject(jsonArray.getString(i), PackageResult.class);
                list.add(packageResult);
            }

        } catch (Exception e) {
            PackageResult packageResult = JSON.parseObject(json, PackageResult.class);
            list.add(packageResult);
        }
        logger.info("---------------------------");
        logger.info("开始执行安装！");
        for (PackageResult packageResult : list) {
            packageResult.setInstallPackageId(pkValue);
            metaUpgradeModulePackageRpcService.installModule(packageResult);
            rbacUpgradeModulePackageRpcService.installModule(buildRbacPackageResult(packageResult));
            workflowUpgradeModulePackageRpcService.installModule(buildWorkFlowPackageResult(packageResult));
            List<PackageFile> fileList = packageResult.getFiles();
            String tempDir = environment.getProperty("servicecomb.downloads.directory");
            File outputDir = new File(tempDir, File.separator + UUID.randomUUID().toString());
            Map<String, File> uploadFiles = getUpgradeZipFile(file, outputDir);
            for (PackageFile packageFile : fileList) {
                InternalFileUpload internalFileUpload = new InternalFileUpload();
                String value = packageFile.getValue();
                JSONArray fileJsonArray = new JSONArray();
                try {
                    fileJsonArray = JSONArray.parseArray(value);
                } catch (Exception e) {
                    continue;
                }
                try {
                    for (int i = 0; i < fileJsonArray.size(); i++) {
                        JSONObject fileInfo = fileJsonArray.getJSONObject(i);
                        internalFileUpload.setFileName(fileInfo.getString("relName"));
                        internalFileUpload.setFileKey(fileInfo.getString("fileKey"));
                        Optional<MediaType> mediaType = MediaTypeFactory.getMediaType(fileInfo.getString("relName"));
                        internalFileUpload.setContentType(mediaType.orElse(MediaType.APPLICATION_OCTET_STREAM).toString());
                        List<String> deleteFileKeys = new ArrayList<>();
                        deleteFileKeys.add(fileInfo.getString("fileKey"));
                        //先删除文件，再上传
                        documentInternalRpcService.deleteByFileKeys(deleteFileKeys, SecurityUserHolder.getCurrentAccountRealUserId());
                        File upFile = uploadFiles.get(fileInfo.getString("fileName"));
                        documentInternalRpcService.saveMetaPackageZip(internalFileUpload,
                                upFile.getPath(), fileInfo.getString("relName"));
                    }
                } catch (Exception e) {
                    continue;
                }
            }

            if (metaService.select("JE_CORE_RESOURCETABLE",
                    ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", "JE_META_UPGRADERESOURCE_IMPL")).size() > 0) {
                List<DynaBean> upgradeResources = packageResult.getUpgradeResources();
                for (DynaBean dynaBean : upgradeResources) {
                    dynaBean.set(BeanService.KEY_TABLE_CODE, "JE_META_UPGRADERESOURCE_IMPL");
                    dynaBean.setStr("JE_META_UPGRADERESOURCE_ID", UUID.randomUUID().toString());
                    dynaBean.setStr("JE_META_UPGRADEPACKAGE_ID", pkValue);
                    metaService.insert(dynaBean);
                }
            }
            upgradepackageRemark.append(packageResult.getUpgrade().getStr("UPGRADEPACKAGE_REMARK") + "   ");
        }
        return upgradepackageRemark.toString();
    }

    private static Map<String, File> getUpgradeZipFile(File zipFile, File outputDir) {
        Map<String, File> fileMap = new HashMap<>();
        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                if (!entry.isDirectory()) {
                    File outFile = new File(outputDir, entry.getName());

                    // 创建输出文件的目录结构
                    outFile.getParentFile().mkdirs();

                    try (FileOutputStream fos = new FileOutputStream(outFile)) {
                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = zis.read(buffer)) > 0) {
                            fos.write(buffer, 0, len);
                        }
                    }

                    fileMap.put(entry.getName(), outFile);
                }
                zis.closeEntry();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return fileMap;
    }

    private static String getcontentJson(File file) {
        logger.info("-------------------------------------");
        logger.info("正在读取json信息");
        StringBuilder content = new StringBuilder();
        try (ZipFile zipFile = new ZipFile(file, StandardCharsets.UTF_8)) {
            ZipEntry zipEntry = zipFile.getEntry(UpgradeFilePathEnum.CONTENT.getPath());
            if (zipEntry != null) {
                try (InputStream inputStream = zipFile.getInputStream(zipEntry);
                     BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8), 32192)) { // 32KB缓冲区
                    String line;
                    while ((line = reader.readLine()) != null) {
                        content.append(line).append(System.lineSeparator());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        logger.info("读取完毕！");
        return content.toString();
    }

    /**
     * 1.检查数据库表
     * 2.检查资源表的code和功能code是否重复
     * 3.在插入用户数据时检查表是否存在
     *
     * @param pkValue
     * @return
     */
    @Override
    public String doCheck(String pkValue) {
        DynaBean dynaBean = metaService.selectOneByPk("JE_META_UPGRADEINSTALL", pkValue);
        String fileKey = dynaBean.getStr("UPGRADEINSTALL_FILE_KEY");
        File file = documentInternalRpcService.readFile(fileKey);
        String json = getcontentJson(file);
        String result = "";

        List<PackageResult> list = new ArrayList<>();
        try {
            JSONArray jsonArray = JSONArray.parseArray(json);
            for (int i = 0; i < jsonArray.size(); i++) {
                PackageResult packageResult = JSON.parseObject(jsonArray.getString(i), PackageResult.class);
                packageResult.setInstallPackageId(pkValue);
                list.add(packageResult);
            }
        } catch (Exception e) {
            PackageResult packageResult = JSON.parseObject(json, PackageResult.class);
            packageResult.setInstallPackageId(pkValue);
            list.add(packageResult);
        }

        for (PackageResult packageResult : list) {
            result = metaUpgradeModulePackageRpcService.doCheck(packageResult);
            if (StringUtil.isNotEmpty(result)) {
                return result;
            }
            result = rbacUpgradeModulePackageRpcService.doCheck(packageResult);
            if (StringUtil.isNotEmpty(result)) {
                return result;
            }
        }
        return null;
    }

    @Override
    public void doSave(DynaBean dynaBean) {
        String fileKey = dynaBean.getStr("UPGRADEINSTALL_FILE_KEY");
        File file = documentInternalRpcService.readFile(fileKey);
        if (file == null) {
            throw new UpgradeException(MessageUtils.getMessage("upgrade.file.notExits"));
        }

        List<PackageResult> list = new ArrayList<>();
        String json = getcontentJson(file);
        try {
            JSONArray jsonArray = JSONArray.parseArray(json);
            for (int i = 0; i < jsonArray.size(); i++) {
                PackageResult packageResult = JSON.parseObject(jsonArray.getString(i), PackageResult.class);
                list.add(packageResult);
            }
        } catch (Exception e) {
            PackageResult packageResult = JSON.parseObject(json, PackageResult.class);
            list.add(packageResult);
        }

        List<String> ids = new ArrayList<>();
        List<String> names = new ArrayList<>();
        List<String> codes = new ArrayList<>();

        for (PackageResult packageResult : list) {
            DynaBean upgrade = packageResult.getUpgrade();
            dynaBean.setStr("UPGRADEINSTALL_PACKAGE_TIME", upgrade.getStr("UPGRADEPACKAGE_PACKAGE_TIME"));
            dynaBean.set("UPGRADEINSTALL_VERSION", upgrade.getStr("UPGRADEPACKAGE_VERSION"));
            dynaBean.setStr("UPGRADEINSTALL_YWCPMC", upgrade.getStr("UPGRADEPACKAGE_YWCPMC"));
            dynaBean.setStr("UPGRADEINSTALL_YWCPBM", upgrade.getStr("UPGRADEPACKAGE_YWCPBM"));
            ids.add(upgrade.getStr("SY_PRODUCT_ID"));
            names.add(upgrade.getStr("SY_PRODUCT_NAME"));
            codes.add(upgrade.getStr("SY_PRODUCT_CODE"));
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", dynaBean.getStr("UPGRADEINSTALL_NAME"));
        jsonObject.put("fileKey", dynaBean.getStr("UPGRADEINSTALL_FILE_KEY"));
        dynaBean.setStr("UPGRADEINSTALL_PACKAGE_FILE", jsonObject.toJSONString());
        dynaBean.setStr("UPGRADEINSTALL_INSTALL_CODE", UpgradeInstallStateEnum.NOINSTALL.getValue());
        dynaBean.setStr("UPGRADEINSTALL_INSTALL_NAME", UpgradeInstallStateEnum.NOINSTALL.getName());
        dynaBean.setStr("JE_META_UPGRADEPACKAGE_ID", UUID.randomUUID().toString());
        dynaBean.setStr("SY_PRODUCT_ID", String.join(",", ids));
        dynaBean.setStr("SY_PRODUCT_NAME", String.join(",", names));
        dynaBean.setStr("SY_PRODUCT_CODE", String.join(",", codes));
        dynaBean.setStr("UPGRADEINSTALL_EXECUTION_STATUS", "0");
        commonService.buildModelCreateInfo(dynaBean);
        metaService.insert(dynaBean);
    }

    @Override
    public String importDictionaryFromFuncinfo(String upgradeId) {
        DynaBean upgradePackage = metaService.selectOneByPk("JE_META_UPGRADEPACKAGE", upgradeId);
        /**
         * 1.获取功能的所有字典code
         * 2.对比已导入升级包的字典，存在则去除
         * 3.根据字典codes查找字典表，不为空则存入升级包中
         */
        String result = "";
        List<DynaBean> funcs = metaService.select("JE_META_UPGRADERESOURCE", ConditionsWrapper.builder()
                .eq("JE_META_UPGRADEPACKAGE_ID", upgradeId)
                .eq("UPGRADERESOURCE_TYPE_CODE", "func"));
        if (funcs == null || funcs.size() == 0) {
            return MessageUtils.getMessage("upgrade.not.found.dictionary");
        }
        Set<String> ddCodes = new HashSet();
        for (DynaBean fun : funcs) {
            String funcId = fun.getStr("UPGRADERESOURCE_CONTENT_CODE");
            List<DynaBean> fields = metaService.select("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder()
                    .eq("RESOURCEFIELD_FUNCINFO_ID", funcId)
                    .in("RESOURCEFIELD_XTYPE", "cbbfield", "rgroup", "cgroup", "cbbfield", "treessfield", "treessareafield", "cbblistfield"));
            for (DynaBean field : fields) {
                String configInfo = field.getStr("RESOURCEFIELD_CONFIGINFO");
                if (StringUtil.isNotEmpty(configInfo)) {
                    ddCodes.add(configInfo.split(",")[0]);
                }
            }
        }
        if (ddCodes == null || ddCodes.size() == 0) {
            return MessageUtils.getMessage("upgrade.not.found.dictionary.in.the.funcion");
        }
        //查找已导入到升级包的字典
        Map<String, String> source = metaService.selectSql(
                "select JE_META_UPGRADEPACKAGE_ID,UPGRADERESOURCE_CONTENT_CODE,UPGRADERESOURCE_CONTENT_BM from JE_META_UPGRADERESOURCE " +
                        "where  JE_META_UPGRADEPACKAGE_ID = {0} AND UPGRADERESOURCE_TYPE_CODE='dictionary' ", upgradeId)
                .stream().collect(Collectors.toMap(p -> String.valueOf(p.get("UPGRADERESOURCE_CONTENT_BM")), p -> String.valueOf(p.get("JE_META_UPGRADEPACKAGE_ID"))));

        List<DynaBean> dicts = metaService.select("JE_CORE_DICTIONARY", ConditionsWrapper.builder()
                .in("DICTIONARY_DDCODE", ddCodes).apply("and (SY_STATUS = '' or SY_STATUS = '1' or SY_STATUS is NULL)"));
        for (DynaBean dict : dicts) {
            String ddCode = dict.getStr("DICTIONARY_DDCODE");
            if (source.containsKey(ddCode)) {
                continue;
            }
            DynaBean detailBean = new DynaBean("JE_META_UPGRADERESOURCE", false);
            detailBean.set("UPGRADERESOURCE_TYPE_NAME", "数据字典");
            detailBean.set("UPGRADERESOURCE_TYPE_CODE", "dictionary");
            detailBean.set("UPGRADERESOURCE_CONTENT_NAME", dict.getStr("DICTIONARY_DDNAME"));
            detailBean.set("UPGRADERESOURCE_CONTENT_CODE", dict.getStr("JE_CORE_DICTIONARY_ID"));
            detailBean.set("UPGRADERESOURCE_CONTENT_BM", dict.getStr("DICTIONARY_DDCODE"));
            detailBean.set("JE_META_UPGRADEPACKAGE_ID", upgradeId);
            detailBean.set("UPGRADERESOURCE_CODE", dict.getStr("DICTIONARY_DDCODE"));
            detailBean.set("SY_PRODUCT_CODE", upgradePackage.getStr("SY_PRODUCT_NAME"));
            detailBean.set("SY_PRODUCT_ID", upgradePackage.getStr("SY_PRODUCT_ID"));
            detailBean.set("SY_PRODUCT_NAME", upgradePackage.getStr("SY_PRODUCT_CODE"));
            commonService.buildModelCreateInfo(detailBean);
            metaService.insert(detailBean);
        }
        return result;
    }

    @Override
    public String importTableByFuncinfo(String upgradeId) {
        String result = "";
        List<DynaBean> funcs = metaService.select("JE_META_UPGRADERESOURCE", ConditionsWrapper.builder()
                .eq("JE_META_UPGRADEPACKAGE_ID", upgradeId)
                .eq("UPGRADERESOURCE_TYPE_CODE", "func"));

        if (funcs == null) {
            return MessageUtils.getMessage("upgrade.funcResource.notExits");
        }

        Map<String, String> source = metaService.selectSql(
                "select JE_META_UPGRADEPACKAGE_ID,UPGRADERESOURCE_CONTENT_CODE,UPGRADERESOURCE_CONTENT_BM from JE_META_UPGRADERESOURCE " +
                        "where  JE_META_UPGRADEPACKAGE_ID = {0} AND UPGRADERESOURCE_TYPE_CODE='table' ", upgradeId)
                .stream().collect(Collectors.toMap(p -> String.valueOf(p.get("UPGRADERESOURCE_CONTENT_BM")), p -> String.valueOf(p.get("JE_META_UPGRADEPACKAGE_ID"))));
        if (source == null) {
            source = new HashMap<>();
        }
        Set tableCodes = new HashSet();
        for (DynaBean funSource : funcs) {
            DynaBean funcinfo = metaService.selectOne("JE_CORE_FUNCINFO",
                    ConditionsWrapper.builder().eq("JE_CORE_FUNCINFO_ID", funSource.getStr("UPGRADERESOURCE_CONTENT_CODE")));
            if (!source.containsKey(funcinfo.getStr("FUNCINFO_TABLENAME"))) {
                tableCodes.add(funcinfo.getStr("FUNCINFO_TABLENAME"));
            }
        }
        importTableByTableCodes(tableCodes, upgradeId);
        return result;
    }


    public void importTableByTableCodes(Set tableCodes, String upgradeId) {
        if (tableCodes == null || tableCodes.size() == 0) {
            return;
        }
        List<DynaBean> list = metaService.select("JE_CORE_RESOURCETABLE",
                ConditionsWrapper.builder().in("RESOURCETABLE_TABLECODE", tableCodes));
        DynaBean upgradePackage = metaService.selectOneByPk("JE_META_UPGRADEPACKAGE", upgradeId);
        for (DynaBean table : list) {
            DynaBean detailBean = new DynaBean("JE_META_UPGRADERESOURCE", false);
            detailBean.set("UPGRADERESOURCE_TYPE_NAME", "资源表");
            detailBean.set("UPGRADERESOURCE_TYPE_CODE", "table");
            detailBean.set("UPGRADERESOURCE_CONTENT_BM", table.getStr("RESOURCETABLE_TABLECODE"));
            detailBean.set("UPGRADERESOURCE_CONTENT_NAME", table.getStr("RESOURCETABLE_TABLENAME"));
            detailBean.set("UPGRADERESOURCE_CONTENT_CODE", table.getStr("JE_CORE_RESOURCETABLE_ID"));
            detailBean.set("JE_META_UPGRADEPACKAGE_ID", upgradeId);
            detailBean.set("SY_PRODUCT_CODE", upgradePackage.getStr("SY_PRODUCT_NAME"));
            detailBean.set("SY_PRODUCT_ID", upgradePackage.getStr("SY_PRODUCT_ID"));
            detailBean.set("SY_PRODUCT_NAME", upgradePackage.getStr("SY_PRODUCT_CODE"));
            commonService.buildModelCreateInfo(detailBean);
            metaService.insert(detailBean);
        }
    }

    @Override
    public String saveResources(String oldId, String newId) {
        List<DynaBean> list = metaService.select("JE_META_UPGRADERESOURCE", ConditionsWrapper.builder()
                .eq("JE_META_UPGRADEPACKAGE_ID", oldId));
        List<DynaBean> newList = new ArrayList<>();
        for (DynaBean dynaBean : list) {
            dynaBean.setStr("JE_META_UPGRADERESOURCE_ID", JEUUID.uuid());
            dynaBean.setStr("JE_META_UPGRADEPACKAGE_ID", newId);
            commonService.buildModelCreateInfo(dynaBean);
            newList.add(dynaBean);
        }
        if (newList.size() > 0) {
            metaService.insertBatch(newList);
        }
        return null;
    }

    @Override
    public String getResourceIds(String upgradeId, String upgraderesourceType) {
        List<DynaBean> list = metaService.select("JE_META_UPGRADERESOURCE",
                ConditionsWrapper.builder().eq("UPGRADERESOURCE_TYPE_CODE", upgraderesourceType)
                        .eq("JE_META_UPGRADEPACKAGE_ID", upgradeId).selectColumns("UPGRADERESOURCE_CONTENT_CODE"));
        if (list == null || list.size() == 0) {
            return "";
        }
        String ids = "";
        for (int i = 0; i < list.size(); i++) {
            DynaBean dynaBean = list.get(i);
            if (i == list.size() - 1) {
                ids += dynaBean.getStr("UPGRADERESOURCE_CONTENT_CODE");
            } else {
                ids += dynaBean.getStr("UPGRADERESOURCE_CONTENT_CODE") + ",";
            }
        }
        return ids;
    }


    public void deleteResourceByType(String upgradeId, String type) {
        metaService.delete("JE_META_UPGRADERESOURCE",
                ConditionsWrapper.builder().eq("JE_META_UPGRADEPACKAGE_ID", upgradeId).eq("UPGRADERESOURCE_TYPE_CODE", type));
    }


    @Override
    public void updateState(InternalFileBO fileBO, String fileName, String upgradeId) {
        JSONObject fileObj = new JSONObject();
        fileObj.put("name", fileName);
        fileObj.put("fileKey", fileBO.getFileKey());
        RealOrganizationUser realOrganizationUser = SecurityUserHolder.getCurrentAccount().getRealUser();
        DynaBean dynaBean = new DynaBean("JE_META_UPGRADEPACKAGE", false);
        dynaBean.setStr("UPGRADEPACKAGE_PACKAGE_FILE", fileObj.toJSONString());
        dynaBean.setStr("UPGRADEPACKAGE_PACKAGE_CODE", "1");
        dynaBean.setStr("UPGRADEPACKAGE_PACKAGE_TIME", DateUtils.formatDateTime(new Date()));
        dynaBean.setStr("UPGRADEPACKAGE_PACKAGEUSER_ID", realOrganizationUser.getId());
        dynaBean.setStr("UPGRADEPACKAGE_PACKAGEUSER_NAME", realOrganizationUser.getName());
        commonService.buildModelModifyInfo(dynaBean);
        metaService.update(dynaBean, ConditionsWrapper.builder().eq("JE_META_UPGRADEPACKAGE_ID", upgradeId));
    }


    public InputStream buildListZip(List<PackageResult> packageResults, Map<String, List<DynaBean>> map) {
        String tempDir = null;
        JSONArray packageResultJsonArray = new JSONArray();
        try {
            List<File> files = new ArrayList<>();
            for (PackageResult packageResult : packageResults) {
                String productId = packageResult.getUpgrade().getStr("SY_PRODUCT_ID");
                // 添加附件
                packageResult.setUpgradeResources(map.get(productId));
                String jsonString = JSON.toJSONString(packageResult);
                tempDir = environment.getProperty("servicecomb.downloads.directory") + File.separator + UUID.randomUUID().toString();
                FileUtil.mkdir(tempDir);
                // 将所有文件放到列表中

                List<PackageFile> packageFileList = packageResult.getFiles();
                for (PackageFile packageFile : packageFileList) {
                    String fileKeyInfo = packageFile.getValue();
                    if (Strings.isNullOrEmpty(fileKeyInfo)) {
                        continue;
                    }
                    JSONArray jsonArray;
                    try {
                        jsonArray = JSONArray.parseArray(fileKeyInfo);
                    } catch (Exception e) {
                        continue;
                    }
                    if (jsonArray.size() > 0) {
                        for (int i = 0; i < jsonArray.size(); i++) {
                            JSONObject jsonObject = jsonArray.getJSONObject(i);
                            String fileKey = jsonObject.getString("fileKey");
                            if (Strings.isNullOrEmpty(fileKey)) {
                                continue;
                            }
                            // 模拟文件读取
                            File file = documentInternalRpcService.readFile(fileKey);
                            String decodedFileName = URLDecoder.decode(file.getName(), "UTF-8");
                            jsonObject.put("fileName", decodedFileName);
                            if (!file.exists()) {
                                continue;
                            }
                            files.add(file);
                        }
                    }
                    packageFile.setValue(jsonArray.toString());
                }
                // json文件
                packageResultJsonArray.add(packageResult);
            }

            File jsonFile = FileUtil.writeString(packageResultJsonArray.toString(), tempDir + File.separator + "content.json", StandardCharsets.UTF_8);
            files.add(jsonFile);

            // 创建一个临时的 ZIP 文件
            File zipFile = new File(tempDir + File.separator + "output.zip");

            // 使用 ZipUtil.zip 将多个文件压缩到一个 ZIP 文件中
            ZipUtil.zip(zipFile, StandardCharsets.UTF_8, false, files.toArray(new File[0]));

            // 返回 ZIP 文件的输入流和临时目录路径
            return new TempFileInputStream(zipFile, Paths.get(tempDir));
        } catch (Exception e) {
            e.printStackTrace();
            if (tempDir != null) {
                deleteTempDirectory(Paths.get(tempDir));
            }
            return null;
        }
    }


    @Override
    public InputStream buildZip(PackageResult packageResult, List<DynaBean> functionBeanList) {
        String tempDir = null;
        try {
            // 添加附件
            packageResult.setUpgradeResources(functionBeanList);
            String jsonString = JSON.toJSONString(packageResult);
            tempDir = environment.getProperty("servicecomb.downloads.directory") + File.separator + UUID.randomUUID().toString();
            FileUtil.mkdir(tempDir);
            // 将所有文件放到列表中
            List<File> files = new ArrayList<>();
            List<PackageFile> packageFileList = packageResult.getFiles();
            for (PackageFile packageFile : packageFileList) {
                String fileKeyInfo = packageFile.getValue();
                if (Strings.isNullOrEmpty(fileKeyInfo)) {
                    continue;
                }
                JSONArray jsonArray;
                try {
                    jsonArray = JSONArray.parseArray(fileKeyInfo);
                } catch (Exception e) {
                    continue;
                }
                if (jsonArray.size() > 0) {
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        String fileKey = jsonObject.getString("fileKey");
                        if (Strings.isNullOrEmpty(fileKey)) {
                            continue;
                        }
                        // 模拟文件读取
                        File file = documentInternalRpcService.readFile(fileKey);
                        String decodedFileName = URLDecoder.decode(file.getName(), "UTF-8");
                        jsonObject.put("fileName", decodedFileName);
                        if (!file.exists()) {
                            continue;
                        }
                        files.add(file);
                    }
                }
                packageFile.setValue(jsonArray.toString());
            }
            // json文件
            jsonString = JSON.toJSONString(packageResult);
            File jsonFile = FileUtil.writeString(jsonString, tempDir + File.separator + "content.json", StandardCharsets.UTF_8);
            files.add(jsonFile);

            // 创建一个临时的 ZIP 文件
            File zipFile = new File(tempDir + File.separator + "output.zip");

            // 使用 ZipUtil.zip 将多个文件压缩到一个 ZIP 文件中
            ZipUtil.zip(zipFile, StandardCharsets.UTF_8, false, files.toArray(new File[0]));

            // 返回 ZIP 文件的输入流和临时目录路径
            return new TempFileInputStream(zipFile, Paths.get(tempDir));
        } catch (Exception e) {
            e.printStackTrace();
            if (tempDir != null) {
                deleteTempDirectory(Paths.get(tempDir));
            }
            return null;
        }
    }

    @Override
    public String generateIncrementalUpgradePackage(DynaBean dynaBean, String productCode, String version) {
        Map<String, List<DynaBean>> map = new HashMap<>();
        List<PackageResult> packageResults = new ArrayList<>();
        //打包数据
        List<DynaBean> upgradePackageList = metaService.select("JE_META_UPGRADEPACKAGE", ConditionsWrapper.builder()
                .eq("UPGRADEPACKAGE_YWCPBM", productCode).eq("UPGRADEPACKAGE_VERSION", version)
                .eq("UPGRADEPACKAGE_PACKAGE_CODE", "1").eq("UPGRADEPACKAGE_BBSJB", "1")
        );
        for (DynaBean upgradePackage : upgradePackageList) {
            String resourceProductCode = upgradePackage.getStr("SY_PRODUCT_ID");
            List<DynaBean> functionBeanList = new ArrayList<>();
            if (map.get(resourceProductCode) != null) {
                functionBeanList = map.get(resourceProductCode);
            }
            String type = upgradePackage.getStr("UPGRADEPACKAGE_PLATFORM_CODE");
            if (type.equals("1") || type.equals("0")) {//普通打包
                List<DynaBean> list = metaService.select("JE_META_UPGRADERESOURCE", ConditionsWrapper.builder()
                        .eq("JE_META_UPGRADEPACKAGE_ID", upgradePackage.getStr("JE_META_UPGRADEPACKAGE_ID"))
                        .orderByAsc("SY_ORDERINDEX"));
                functionBeanList.addAll(list);
            } else {//插件打包
                functionBeanList.addAll(buildPluginResources(upgradePackage.getStr("UPGRADEPACKAGE_YWSJ"),
                        upgradePackage.getStr("SY_PRODUCT_ID"),
                        upgradePackage.getStr("SY_PRODUCT_NAME"),
                        upgradePackage.getStr("SY_PRODUCT_CODE")));
            }
            map.put(resourceProductCode, functionBeanList);
        }
        //安装包数据
        List<DynaBean> installUpgrades = metaService.select("JE_META_UPGRADEINSTALL", ConditionsWrapper.builder()
                .eq("UPGRADEINSTALL_YWCPBM", productCode).eq("UPGRADEINSTALL_VERSION", version)
                .eq("UPGRADEINSTALL_INSTALL_CODE", "1").eq("UPGRADEINSTALL_BBSJB", "1")
                .orderByAsc("SY_ORDERINDEX"));
        for (DynaBean installUp : installUpgrades) {
            List<DynaBean> list = metaService.select("JE_META_UPGRADERESOURCE_IMPL", ConditionsWrapper.builder()
                    .eq("JE_META_UPGRADEPACKAGE_ID", installUp.getPkValue()));
            for (DynaBean impl : list) {
                String resourceProductCode = impl.getStr("SY_PRODUCT_ID");
                List<DynaBean> functionBeanList = new ArrayList<>();
                if (map.get(resourceProductCode) != null) {
                    functionBeanList = map.get(resourceProductCode);
                }
                functionBeanList.add(impl);
                map.put(resourceProductCode, functionBeanList);
            }
        }

        if (map.size() == 0) {
            return "";
        }

        totalWeightRemoval(map);


        for (String key : map.keySet()) {
            DynaBean upgradeBean = new DynaBean("JE_META_UPGRADEPACKAGE", true);
            upgradeBean.setStr("UPGRADEPACKAGE_PACKAGE_TIME", DateUtils.formatDateTime(new Date()));
            upgradeBean.set("UPGRADEPACKAGE_VERSION", version);
            upgradeBean.setStr("JE_META_UPGRADEPACKAGE_ID", UUID.randomUUID().toString());
            upgradeBean.setStr("SY_PRODUCT_ID", key);
            DynaBean product = metaService.selectOneByPk("JE_PRODUCT_MANAGE", key);
            upgradeBean.setStr("SY_PRODUCT_CODE", product.getStr("PRODUCT_CODE"));
            upgradeBean.setStr("SY_PRODUCT_NAME", product.getStr("PRODUCT_NAME"));
            upgradeBean.setStr("UPGRADEPACKAGE_YWCPMC", dynaBean.getStr("PROEUCT_CPMC"));
            upgradeBean.setStr("UPGRADEPACKAGE_YWCPBM", dynaBean.getStr("PROEUCT_CPBM"));
            commonService.buildModelCreateInfo(upgradeBean);
            processResourceBeans(upgradeBean, map.get(key));
            PackageResult packageResult = doPackage(upgradeBean);
            packageResults.add(packageResult);
        }

        InputStream zipInputStream = buildListZip(packageResults, map);
        if (zipInputStream == null) {
            return "";
        }
        String tempDir = environment.getProperty("servicecomb.uploads.directory");
        if (!FileUtil.exist(tempDir)) {
            FileUtil.mkdir(tempDir);
        }

        String packageName = dynaBean.getStr("PROEUCT_CPMC") + String.format("【%s】增量升级包.zip", version);
        File zipFile = FileUtil.writeFromStream(zipInputStream, tempDir + File.separator + packageName);
        InternalFileUpload fileUpload = new InternalFileUpload(packageName, "application/zip", Long.valueOf(zipFile.length()));
        InternalFileBO fileBO = null;
        try {
            fileBO = documentInternalRpcService.saveMetaPackageZip(fileUpload, zipFile.getPath(), packageName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String fileInfo = String.format("[{\"fileKey\":\"%s\",\"relName\":\"%s\",\"suffix\":\"zip\",\"size\":%s}]", fileBO.getFileKey(), fileBO.getRelName(), fileBO.getSize());
        return fileInfo;
    }

    private void totalWeightRemoval(Map<String, List<DynaBean>> map) {
        // 全局去重集合
        Set<String> globalUniqueContentCodes = new HashSet<>();

        // 第一步：去重并移除空键
        Iterator<Map.Entry<String, List<DynaBean>>> mapIterator = map.entrySet().iterator();

        while (mapIterator.hasNext()) {
            Map.Entry<String, List<DynaBean>> entry = mapIterator.next();
            List<DynaBean> list = entry.getValue();

            // 使用 Iterator 来安全地在遍历过程中移除元素
            Iterator<DynaBean> listIterator = list.iterator();

            while (listIterator.hasNext()) {
                DynaBean next = listIterator.next();
                String contentCode = next.getStr("UPGRADERESOURCE_CONTENT_CODE");
                String contentType = next.getStr("UPGRADERESOURCE_TYPE_CODE");

                // 如果 globalUniqueContentCodes 中已经包含该 contentCode，则移除该 DynaBean
                if (!globalUniqueContentCodes.add(contentCode + contentType)) {
                    listIterator.remove();
                }
            }

            // 如果 list 为空，则从 map 中移除该键
            if (list.isEmpty()) {
                mapIterator.remove();
            }
        }
    }

    @Override
    public String generateFullUpgradePackage(DynaBean dynaBean, String productCode, String version) {
        Map<String, List<DynaBean>> map = new HashMap<>();
        List<PackageResult> packageResults = new ArrayList<>();

        List<DynaBean> allFunctionBeanList = new ArrayList<>();
        List<DynaBean> resources = metaService.select("JE_META_UPGRADE_PRODUCT_RESOURCE",
                ConditionsWrapper.builder().eq("JE_META_UPGRADE_PROEUCT_ID", dynaBean.getPkValue())
                        .orderByAsc("SY_ORDERINDEX"));
        if (resources.size() == 0) {
            return "";
        }

        buildResourcesToFunctionBeanList(allFunctionBeanList, resources);

        for (DynaBean functionBean : allFunctionBeanList) {
            String resourceProductCode = functionBean.getStr("SY_PRODUCT_ID");
            List<DynaBean> functionBeanList = new ArrayList<>();
            if (map.get(resourceProductCode) != null) {
                functionBeanList = map.get(resourceProductCode);
            }
            functionBeanList.add(functionBean);
            map.put(resourceProductCode, functionBeanList);
        }

        if (map.size() == 0) {
            return "";
        }

        totalWeightRemoval(map);

        for (String key : map.keySet()) {
            DynaBean upgradeBean = new DynaBean("JE_META_UPGRADEPACKAGE", true);
            upgradeBean.setStr("UPGRADEPACKAGE_PACKAGE_TIME", DateUtils.formatDateTime(new Date()));
            upgradeBean.set("UPGRADEPACKAGE_VERSION", version);
            upgradeBean.setStr("JE_META_UPGRADEPACKAGE_ID", UUID.randomUUID().toString());
            upgradeBean.setStr("SY_PRODUCT_ID", key);
            DynaBean product = metaService.selectOneByPk("JE_PRODUCT_MANAGE", key);
            upgradeBean.setStr("SY_PRODUCT_CODE", product.getStr("PRODUCT_CODE"));
            upgradeBean.setStr("SY_PRODUCT_NAME", product.getStr("PRODUCT_NAME"));
            upgradeBean.setStr("UPGRADEPACKAGE_YWCPMC", dynaBean.getStr("PROEUCT_CPMC"));
            upgradeBean.setStr("UPGRADEPACKAGE_YWCPBM", dynaBean.getStr("PROEUCT_CPBM"));
            commonService.buildModelCreateInfo(upgradeBean);
            processResourceBeans(upgradeBean, map.get(key));
            PackageResult packageResult = doPackage(upgradeBean);
            packageResults.add(packageResult);
        }

        InputStream zipInputStream = buildListZip(packageResults, map);
        if (zipInputStream == null) {
            return "";
        }
        String tempDir = environment.getProperty("servicecomb.uploads.directory");
        if (!FileUtil.exist(tempDir)) {
            FileUtil.mkdir(tempDir);
        }

        String packageName = dynaBean.getStr("PROEUCT_CPMC") + String.format("【%s】全量升级包.zip", version);
        File zipFile = FileUtil.writeFromStream(zipInputStream, tempDir + File.separator + packageName);
        InternalFileUpload fileUpload = new InternalFileUpload(packageName, "application/zip", Long.valueOf(zipFile.length()));
        InternalFileBO fileBO = null;
        try {
            fileBO = documentInternalRpcService.saveMetaPackageZip(fileUpload, zipFile.getPath(), packageName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String fileInfo = String.format("[{\"fileKey\":\"%s\",\"relName\":\"%s\",\"suffix\":\"zip\",\"size\":%s}]", fileBO.getFileKey(), fileBO.getRelName(), fileBO.getSize());
        return fileInfo;
    }

    private void buildResourcesToFunctionBeanList(List<DynaBean> functionBeanList, List<DynaBean> resources) {
        for (DynaBean resource : resources) {
            //业务数据
            if (resource.getStr("RESOURCE_RESOURCE_CODE").equals("bean")) {
                DynaBean functionBean = new DynaBean("JE_META_UPGRADERESOURCE", true);
                functionBean.setStr("UPGRADERESOURCE_TYPE_CODE", UpgradeResourcesEnum.BUSINESS.getType());
                functionBean.setStr("UPGRADERESOURCE_CONTENT_VALUE", resource.getStr("RESOURCE_TJSQL"));
                functionBean.setStr("UPGRADERESOURCE_FILE_FIELD", resource.getStr("RESOURCE_FJZD"));
                DynaBean table = metaService.selectOne("JE_CORE_RESOURCETABLE",
                        ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", resource.getStr("RESOURCE_ZYBM")));
                functionBean.setStr("UPGRADERESOURCE_CONTENT_CODE", table.getPkValue());
                functionBean.setStr("UPGRADERESOURCE_CONTENT_NAME", table.getStr("RESOURCETABLE_TABLENAME"));
                functionBean.set("SY_PRODUCT_CODE", resource.getStr("SY_PRODUCT_NAME"));
                functionBean.set("SY_PRODUCT_ID", resource.getStr("SY_PRODUCT_ID"));
                functionBean.set("SY_PRODUCT_NAME", resource.getStr("SY_PRODUCT_CODE"));
                functionBean.set("SY_ORDERINDEX", resource.getStr("SY_ORDERINDEX"));
                commonService.buildModelCreateInfo(functionBean);
                functionBeanList.add(functionBean);
            } else if (resource.getStr("RESOURCE_RESOURCE_CODE").equals("pluginData")) {
                functionBeanList.addAll(buildPluginResources(
                        resource.getStr("RESOURCE_TJSJ"), resource.getStr("SY_PRODUCT_ID")
                        , resource.getStr("SY_PRODUCT_NAME"), resource.getStr("SY_PRODUCT_CODE")));
            } else {
                String ids = resource.getStr("RESOURCE_ZYID");
                addFunctionBeanList(functionBeanList, resource,
                        UpgradeResourcesEnum.getUpgradeResourcesEnumByType(resource.getStr("RESOURCE_RESOURCE_CODE")), ids);
            }
        }
    }


    private void addFunctionBeanList(List<DynaBean> functionBeanList, DynaBean resource, UpgradeResourcesEnum upgradeResourcesEnum, String ids) {
        String names = resource.getStr("RESOURCE_ZYMC");
        String bms = resource.getStr("RESOURCE_ZYBM");
        String[] nameArray = names.split(",");
        String[] idArray = ids.split(",");
        String[] bmArray = bms.split(",");
        for (int i = 0; i < nameArray.length; i++) {
            DynaBean functionBean = new DynaBean("JE_META_UPGRADERESOURCE", true);
            functionBean.setStr("UPGRADERESOURCE_TYPE_CODE", upgradeResourcesEnum.getType());
            functionBean.setStr("UPGRADERESOURCE_TYPE_NAME", upgradeResourcesEnum.getName());
            functionBean.setStr("UPGRADERESOURCE_CONTENT_CODE", idArray[i]);
            functionBean.setStr("UPGRADERESOURCE_CONTENT_BM", bmArray[i]);
            functionBean.setStr("UPGRADERESOURCE_CONTENT_NAME", nameArray[i]);
            functionBean.set("SY_PRODUCT_CODE", resource.getStr("SY_PRODUCT_NAME"));
            functionBean.set("SY_PRODUCT_ID", resource.getStr("SY_PRODUCT_ID"));
            functionBean.set("SY_PRODUCT_NAME", resource.getStr("SY_PRODUCT_CODE"));
            commonService.buildModelCreateInfo(functionBean);
            functionBeanList.add(functionBean);
        }
    }


    public void processResourceBeans(DynaBean upgradeBean, List<DynaBean> functionBeanList) {
        Map<String, String> businessFileField = new HashMap<>();
        for (DynaBean eachResourceBean : functionBeanList) {
            UpgradeResourcesEnum upgradeResourcesEnum = UpgradeResourcesEnum.getUpgradeResourcesEnumByType(eachResourceBean.getStr("UPGRADERESOURCE_TYPE_CODE"));
            Object resourceObject = upgradeBean.get(upgradeResourcesEnum.getAddListName());

            //业务数据单独处理
            if (upgradeResourcesEnum == UpgradeResourcesEnum.BUSINESS) {
                Map<String, String> businessMap = new LinkedHashMap<>();
                if (resourceObject == null) {
                    upgradeBean.put(upgradeResourcesEnum.getAddListName(), businessMap);
                } else {
                    businessMap = (Map<String, String>) resourceObject;
                }
                String whereSql = eachResourceBean.getStr("UPGRADERESOURCE_CONTENT_VALUE");
                if (Strings.isNullOrEmpty(whereSql)) {
                    whereSql = " AND 1=1";
                }
                String tableId = eachResourceBean.getStr("UPGRADERESOURCE_CONTENT_CODE");
                DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", tableId);
                //如果有重复的
                if (businessMap.get(table.getStr("RESOURCETABLE_TABLECODE")) != null) {
                    String sqlBuffer = businessMap.get(table.getStr("RESOURCETABLE_TABLECODE"));
                    sqlBuffer += String.format(" OR (%s)", whereSql);
                    businessMap.put(table.getStr("RESOURCETABLE_TABLECODE"), sqlBuffer);
                } else {
                    businessMap.put(table.getStr("RESOURCETABLE_TABLECODE"), whereSql);
                }
                //设置业务数据附件字段
                if (!Strings.isNullOrEmpty(eachResourceBean.getStr("UPGRADERESOURCE_FILE_FIELD"))) {
                    if (businessFileField.get(table.getStr("RESOURCETABLE_TABLECODE")) != null) {
                        String fields = businessFileField.get(table.getStr("RESOURCETABLE_TABLECODE"));
                        businessFileField.put(table.getStr("RESOURCETABLE_TABLECODE"), fields + "," + eachResourceBean.getStr("UPGRADERESOURCE_FILE_FIELD"));
                    } else {
                        businessFileField.put(table.getStr("RESOURCETABLE_TABLECODE"), eachResourceBean.getStr("UPGRADERESOURCE_FILE_FIELD"));
                    }
                }
                continue;
            }

            //其他数据统一处理
            List<String> resourceList = new ArrayList<>();
            if (resourceObject == null) {
                upgradeBean.put(upgradeResourcesEnum.getAddListName(), resourceList);
            } else {
                resourceList = (List<String>) resourceObject;
            }
            if (!resourceList.contains(eachResourceBean.getStr("UPGRADERESOURCE_CONTENT_CODE"))) {
                resourceList.add(eachResourceBean.getStr("UPGRADERESOURCE_CONTENT_CODE"));
            }
        }

        upgradeBean.put("businessFileField", businessFileField);
    }

    @Override
    public List<DynaBean> buildPluginResources(String jsonStr, String SY_PRODUCT_ID, String SY_PRODUCT_NAME, String SY_PRODUCT_CODE) {
        List<DynaBean> list = new ArrayList<>();
        try {
            buildPlugResourcesToFunctionBeanList(list, jsonStr, SY_PRODUCT_ID, SY_PRODUCT_NAME, SY_PRODUCT_CODE);
            return list;
        } catch (Exception e) {
            return list;
        }
    }

    private void buildPlugResourcesToFunctionBeanList(List<DynaBean> functionBeanList, String jsonStr,
                                                      String SY_PRODUCT_ID, String SY_PRODUCT_NAME, String SY_PRODUCT_CODE) {
        if (Strings.isNullOrEmpty(jsonStr)) {
            return;
        }
        JSONArray jsonArray;
        try {
            jsonArray = JSONArray.parseArray(jsonStr);
        } catch (Exception e) {
            return;
        }

        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            UpgradeResourcesEnum upgradeResourcesEnum = UpgradeResourcesEnum.getUpgradeResourcesEnumByType(jsonObject.getString("UPGRADERESOURCE_TYPE_CODE"));
            DynaBean functionBean = new DynaBean("JE_META_UPGRADERESOURCE", true);
            functionBean.setStr("UPGRADERESOURCE_TYPE_CODE", upgradeResourcesEnum.getType());
            functionBean.setStr("UPGRADERESOURCE_TYPE_NAME", upgradeResourcesEnum.getName());
            functionBean.setStr("UPGRADERESOURCE_CONTENT_CODE", jsonObject.getString("UPGRADERESOURCE_CONTENT_CODE"));
            functionBean.setStr("UPGRADERESOURCE_CONTENT_BM", jsonObject.getString("UPGRADERESOURCE_CONTENT_BM"));
            functionBean.setStr("UPGRADERESOURCE_CONTENT_NAME", jsonObject.getString("UPGRADERESOURCE_CONTENT_NAME"));
            functionBean.set("SY_PRODUCT_CODE", SY_PRODUCT_CODE);
            functionBean.set("SY_PRODUCT_ID", SY_PRODUCT_ID);
            functionBean.set("SY_PRODUCT_NAME", SY_PRODUCT_NAME);
            commonService.buildModelCreateInfo(functionBean);
            functionBeanList.add(functionBean);
        }
    }

    private PackageResult buildWorkFlowPackageResult(PackageResult packageResult) {
        PackageResult workflowPackageResult = new PackageResult();
        workflowPackageResult.setProductWorkflows(packageResult.getProductWorkflows());
        workflowPackageResult.setInstallPackageId(packageResult.getInstallPackageId());
        return workflowPackageResult;
    }

    private PackageResult buildRbacPackageResult(PackageResult packageResult) {
        PackageResult rbacPackageResult = new PackageResult();
        rbacPackageResult.setRolePerms(packageResult.getRolePerms());
        rbacPackageResult.setProductRoles(packageResult.getProductRoles());
        rbacPackageResult.setProductMenus(packageResult.getProductMenus());
        rbacPackageResult.setProductTopMenus(packageResult.getProductTopMenus());
        rbacPackageResult.setProductPerms(packageResult.getProductPerms());
        rbacPackageResult.setInstallPackageId(packageResult.getInstallPackageId());
        return rbacPackageResult;
    }


    private void deleteTempDirectory(Path dirPath) {
        try {
            Files.walk(dirPath)
                    .sorted((path1, path2) -> path2.compareTo(path1)) // 先删除子文件/目录，再删除父目录
                    .forEach(path -> {
                        try {
                            Files.deleteIfExists(path);
                            System.out.println("Deleted: " + path);
                        } catch (Exception e) {
                            System.err.println("Failed to delete: " + path);
                            e.printStackTrace();
                        }
                    });
        } catch (Exception e) {
            System.err.println("Failed to delete directory: " + dirPath);
            e.printStackTrace();
        }
    }

    private class TempFileInputStream extends FileInputStream {
        private final Path tempDir;

        public TempFileInputStream(File file, Path tempDir) throws Exception {
            super(file);
            this.tempDir = tempDir;
        }

        @Override
        public void close() {
            try {
                super.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                deleteTempDirectory(tempDir);
            }
        }
    }

}
